home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / ANSI folder / INTO Runtime ƒ / C++ 68K ƒ / Sources ƒ / New68K.cp < prev    next >
Encoding:
Text File  |  1994-08-07  |  12.3 KB  |  408 lines  |  [TEXT/MMCC]

  1. /************************************************************************/
  2. /*    Project...:    Standard C++ Library                                    */
  3. /*    Name......:    New.cp                                                    */
  4. /*    Purpose...:    standard C++ library                                    */
  5. /*  Copyright.: ©Copyright 1994 by metrowerks inc. All rights reserved. */
  6. /************************************************************************/
  7.  
  8. #include <new.h>
  9. #include <Memory.h>
  10.  
  11. #pragma a6frames on
  12.  
  13. #define NEWMODE NEWMODE_FAST        //    mode used to compile this file
  14.  
  15. #define NEWMODE_NONE    0            //    do not define operator new/delete
  16. #define NEWMODE_SIMPLE    1            //    call NewPtr/DisposPtr
  17. #define NEWMODE_MALLOC    2            //    use malloc/free
  18. #define NEWMODE_NORMAL    3            //    regular new/delete
  19. #define NEWMODE_FAST    4            //    regular new/delete fast version
  20.  
  21. #define NEWMODE_NORMAL_FASTFREE    0    //    NEWMODE_NORMAL faster free (real bad fragmentation)
  22.  
  23.         // These macros are allow DebugNew.cp to redefine operators
  24.         // new and delete in debug mode while not adding any overhead
  25.         // for the non-debug case.
  26.  
  27. #ifndef OPERATOR_NEW
  28. #define OPERATOR_NEW operator new
  29. #endif
  30. #ifndef OPERATOR_DELETE
  31. #define OPERATOR_DELETE operator delete
  32. #endif
  33.  
  34. extern void (*new_handler)();
  35.  
  36. #if NEWMODE==NEWMODE_SIMPLE
  37.  
  38. /************************************************************************/
  39. /*    Purpose..:     Allocate memory                                            */
  40. /*    Input....:    size of memory to allocate                                */
  41. /*    Return...:    pointer to memory or 0L                                    */
  42. /************************************************************************/
  43. void *OPERATOR_NEW(size_t /* size */,void *p)
  44. {
  45.     return p;
  46. }
  47.  
  48. /************************************************************************/
  49. /*    Purpose..:     Allocate memory                                            */
  50. /*    Input....:    size of memory to allocate                                */
  51. /*    Return...:    pointer to memory or 0L                                    */
  52. /************************************************************************/
  53. void *OPERATOR_NEW(size_t size)
  54. {
  55.     void *ptr;
  56.  
  57.     while((ptr=NewPtr(size))==NULL)
  58.     {
  59.         if(new_handler) new_handler(); else return(NULL);
  60.     }
  61.     return(ptr);
  62. }
  63.  
  64. /************************************************************************/
  65. /*    Purpose..:     Dispose memory                                            */
  66. /*    Input....:    pointer to memory or 0L (no action if 0L)                */
  67. /*    Return...:    ---                                                        */
  68. /************************************************************************/
  69. void OPERATOR_DELETE(void *ptr)
  70. {
  71.     if(ptr) DisposPtr((Ptr)ptr);
  72. }
  73.  
  74. #elif NEWMODE==NEWMODE_MALLOC
  75.  
  76. #include <stdlib.h>
  77.  
  78. /************************************************************************/
  79. /*    Purpose..:     Allocate memory                                            */
  80. /*    Input....:    size of memory to allocate                                */
  81. /*    Return...:    pointer to memory or 0L                                    */
  82. /************************************************************************/
  83. void *OPERATOR_NEW(size_t /* size */,void *p)
  84. {
  85.     return p;
  86. }
  87.  
  88. /************************************************************************/
  89. /*    Purpose..:     Allocate memory                                            */
  90. /*    Input....:    size of memory to allocate                                */
  91. /*    Return...:    pointer to memory or 0L                                    */
  92. /************************************************************************/
  93. void *OPERATOR_NEW(size_t size)
  94. {
  95.     void *ptr;
  96.  
  97.     while((ptr=malloc(size))==NULL)
  98.     {
  99.         if(new_handler) new_handler(); else return(NULL);
  100.     }
  101.     return(ptr);
  102. }
  103.  
  104. /************************************************************************/
  105. /*    Purpose..:     Dispose memory                                            */
  106. /*    Input....:    pointer to memory or 0L (no action if 0L)                */
  107. /*    Return...:    ---                                                        */
  108. /************************************************************************/
  109. void OPERATOR_DELETE(void *ptr)
  110. {
  111.     free(ptr);
  112. }
  113.  
  114. #elif NEWMODE==NEWMODE_NORMAL
  115.  
  116. typedef struct FreeMemList {
  117.     struct FreeMemList    *next;
  118.     long                size;
  119. }    FreeMemList;
  120.  
  121. static FreeMemList    memlist;                //    dummy header block (always empty)
  122. static size_t _newpoolsize    = 0x00010000L;    //    number of bytes allocated for a new pool
  123. static size_t _newnonptrmax    = 0x00001000L;    //    any object bigger than this will call NewPtr(...) directly 
  124.  
  125. /************************************************************************/
  126. /*    Purpose..:     Set size of future allocation pools                        */
  127. /*    Input....:    size of future allocation pools                            */
  128. /*    Return...:    ---                                                        */
  129. /************************************************************************/
  130. void _set_newpoolsize(size_t size)
  131. {
  132.     _newpoolsize=size;
  133. }
  134.  
  135. /************************************************************************/
  136. /*    Purpose..:     Set NewPtr(...) pointer threshold                        */
  137. /*    Input....:    size of new threshold                                    */
  138. /*    Return...:    ---                                                        */
  139. /************************************************************************/
  140. void _set_newnonptrmax(size_t size)
  141. {
  142.     _newnonptrmax=size;
  143. }
  144.  
  145. /************************************************************************/
  146. /*    Purpose..:     Preallocate an allocation pool                            */
  147. /*    Input....:    size of pool to allocate                                */
  148. /*    Return...:    1: no error; 0:    fail                                    */
  149. /************************************************************************/
  150. char _prealloc_newpool(size_t size)
  151. {
  152.     FreeMemList    *list;
  153.  
  154.     if((list=(FreeMemList *)NewPtr(size))==NULL) return 0;
  155.     list->next=memlist.next; list->size=size; memlist.next=list;
  156.     return 1;
  157. }
  158.  
  159. /************************************************************************/
  160. /*    Purpose..:     Allocate memory                                            */
  161. /*    Input....:    size of memory to allocate                                */
  162. /*    Return...:    pointer to memory or 0L                                    */
  163. /************************************************************************/
  164. void *OPERATOR_NEW(size_t /* size */,void *p)
  165. {
  166.     return p;
  167. }
  168.  
  169. /************************************************************************/
  170. /*    Purpose..:     Allocate memory                                            */
  171. /*    Input....:    size of memory to allocate                                */
  172. /*    Return...:    pointer to memory or 0L                                    */
  173. /************************************************************************/
  174. void *OPERATOR_NEW(size_t size)
  175. {
  176.     Ptr ptr;
  177.  
  178.     size=(size&0xFFFFFFFC)+8;        //    alloc *4 quantity plus 4 extra bytes for size
  179.  
  180.     if(size>=_newnonptrmax)
  181.     {    //    try to get pointer from OS
  182.         while(1)
  183.         {
  184.             if((ptr=NewPtr(size))!=NULL) { *(long *)ptr=-1L; return(ptr+4); }
  185.             if(new_handler) new_handler(); else return(NULL);
  186.         }            
  187.     }
  188.  
  189.     while(1)
  190.     {
  191.         FreeMemList    *list,*prev;
  192.  
  193.         for(prev=&memlist,list=prev->next; list; prev=list,list=list->next) if(size<=list->size)
  194.         {
  195. alloc:        if(list->size>=size+sizeof(FreeMemList))
  196.             {    //    split this free block
  197.                 list->size-=size; ptr=(Ptr)list+list->size;
  198.                 *(long *)ptr=size; return(ptr+4);
  199.             }
  200.             //    remove this block from list
  201.             prev->next=list->next; *(long *)list=list->size; return((Ptr)list+4);
  202.         }
  203.     
  204.         //    not enough free memory in memlist (try to allocate a new Ptr from OS
  205.         if((list=(FreeMemList *)NewPtr(_newpoolsize))==NULL)
  206.         {    //    try to allocate a system block
  207.             if((ptr=NewPtr(size))!=NULL) { *(long *)ptr=-1L; return(ptr+4); }
  208.             if(new_handler) new_handler(); else return(NULL);
  209.         }
  210.         else
  211.         {
  212.             list->next=memlist.next; list->size=_newpoolsize;
  213.             memlist.next=list; prev=&memlist; goto alloc;
  214.         }
  215.     }
  216. }
  217.  
  218. /************************************************************************/
  219. /*    Purpose..:     Dispose memory                                            */
  220. /*    Input....:    pointer to memory or 0L (no action if 0L)                */
  221. /*    Return...:    ---                                                        */
  222. /************************************************************************/
  223. void OPERATOR_DELETE(void *ptr)
  224. {
  225.     if(ptr)
  226.     {
  227.         long    size;
  228.  
  229.         ptr=(Ptr)ptr-4; size=*(long *)ptr;
  230.         if(size!=-1L)
  231.         {
  232.             FreeMemList    *list;
  233. #if !NEWMODE_NORMAL_FASTFREE
  234.             FreeMemList    *prev;
  235.             char        merge=0;
  236.  
  237.             for(prev=&memlist,list=prev->next; list; prev=list,list=list->next)
  238.             {
  239.                 if((Ptr)ptr+size==(Ptr)list)
  240.                 {    //    merge block in front of this list item
  241.                     prev->next=list->next; size+=list->size; list=prev;
  242.                     if(merge) break; else { merge=1; continue; }
  243.                 }
  244.                 if((Ptr)ptr==(Ptr)list+list->size)
  245.                 {    //    merge block at the end of this list item
  246.                     prev->next=list->next; ptr=list; size+=list->size; list=prev;
  247.                     if(merge) break; else { merge=1; continue; }
  248.                 }
  249.             }
  250. #endif
  251.             list=(FreeMemList *)ptr; list->next=memlist.next; list->size=size; memlist.next=list;
  252.         }
  253.         else DisposPtr((Ptr)ptr);
  254.     }
  255. }
  256.  
  257. #elif NEWMODE==NEWMODE_FAST
  258.  
  259. typedef struct MemPool {
  260.     struct MemPool        *next;                //    pointer to next pool
  261.     size_t                size;                //    number of bytes in pool (including header)
  262.     char                data[];                //    variable size user data section
  263. }    MemPool;
  264.  
  265. static MemPool    *mempools;                        //    list of memory pools
  266. static char        *lastfree;                        //    pointer to last free block
  267. static char        *lastend;                        //    pointer to last end
  268. static size_t    _newpoolsize    = 0x00010000L;    //    number of bytes allocated for a new pool
  269. static size_t    _newnonptrmax    = 0x00001000L;    //    any object bigger than this will call NewPtr(...) directly 
  270.  
  271. /************************************************************************/
  272. /*    Purpose..:     Set size of future allocation pools                        */
  273. /*    Input....:    size of future allocation pools                            */
  274. /*    Return...:    ---                                                        */
  275. /************************************************************************/
  276. void _set_newpoolsize(size_t size)
  277. {
  278.     _newpoolsize=size;
  279. }
  280.  
  281. /************************************************************************/
  282. /*    Purpose..:     Set NewPtr(...) pointer threshold                        */
  283. /*    Input....:    size of new threshold                                    */
  284. /*    Return...:    ---                                                        */
  285. /************************************************************************/
  286. void _set_newnonptrmax(size_t size)
  287. {
  288.     _newnonptrmax=size;
  289. }
  290.  
  291. /************************************************************************/
  292. /*    Purpose..:     Preallocate a memory pool                                */
  293. /*    Input....:    size of pool to allocate                                */
  294. /*    Return...:    1: no error; 0:    fail                                    */
  295. /************************************************************************/
  296. char _prealloc_newpool(size_t size)
  297. {
  298.     MemPool    *pool;
  299.  
  300.     if((pool=(MemPool *)NewPtr(size))==NULL) return 0;
  301.  
  302.     pool->next=mempools; mempools=pool;
  303.     pool->size=size; *(long *)pool->data=pool->size-sizeof(MemPool);
  304.  
  305.     return 1;
  306. }
  307.  
  308. /************************************************************************/
  309. /*    Purpose..:     Allocate memory                                            */
  310. /*    Input....:    size of memory to allocate                                */
  311. /*    Return...:    pointer to memory or 0L                                    */
  312. /************************************************************************/
  313. void *OPERATOR_NEW(size_t /* size */,void *p)
  314. {
  315.     return p;
  316. }
  317.  
  318. /************************************************************************/
  319. /*    Purpose..:     Allocate memory                                            */
  320. /*    Input....:    size of memory to allocate                                */
  321. /*    Return...:    pointer to memory or 0L                                    */
  322. /************************************************************************/
  323. void *OPERATOR_NEW(size_t size)
  324. {
  325.     MemPool    *pool;
  326.     char    *ptr,*end;
  327.     long    bsize,nsize;
  328.  
  329.     size=(size&0xFFFFFFFC)+8; //    alloc *4 quantity plus 4 bytes for size
  330.  
  331.     while(1)
  332.     {
  333.         if(size>=_newnonptrmax && (ptr=(char *)NewPtr(size))!=NULL)
  334.         {
  335.             *(long *)ptr=0L; return ptr+4;
  336.         }
  337.  
  338.         if((ptr=lastfree)!=0L && (bsize=*(long *)ptr)>=(long)size)
  339.         {    //    last free block has enough memory left
  340.             end=lastend; goto alloc2;
  341.         }
  342.  
  343.         for(pool=mempools; pool; pool=pool->next)
  344.         {
  345. alloc:        for(ptr=pool->data,end=(Ptr)pool+pool->size; ptr<end;) if((bsize=*(long *)ptr)>0)
  346.             {
  347. alloc2:            lastfree=0L;
  348.                 while(ptr+bsize<end && (nsize=*(long *)(ptr+bsize))>0)
  349.                 {    //    merge block with the next block
  350.                     *(long *)ptr=bsize=bsize+nsize;
  351.                 }
  352.                 if(bsize>=size)
  353.                 {    //    pool block is big enough
  354.                     if(bsize>=size+8)
  355.                     {    //    split this block
  356.                         lastfree=ptr; lastend=end;
  357.                         bsize-=size; *(long *)ptr=bsize; ptr+=bsize;
  358.                         *(long *)ptr=-size; return ptr+4;
  359.                     }
  360.                     else
  361.                     {    //    allocate whole block
  362.                         *(long *)ptr=-bsize; return ptr+4;
  363.                     }
  364.                 }
  365.                 else ptr+=bsize;
  366.             }
  367.             else ptr-=bsize;
  368. next:;    }
  369.  
  370.         //    not enough free memory in mempools (try to allocate a new Ptr from OS)
  371.         if((pool=(MemPool *)NewPtr(_newpoolsize))!=NULL)
  372.         {
  373.             pool->next=mempools; mempools=pool;
  374.             pool->size=_newpoolsize; *(long *)pool->data=pool->size-sizeof(MemPool);
  375.             goto alloc;
  376.         }
  377.         else
  378.         {    //    try to allocate a system block
  379.             if((ptr=(char *)NewPtr(size))!=NULL)
  380.             {
  381.                 *(long *)ptr=0L; return ptr+4;
  382.             }
  383.         }
  384.  
  385.         if(new_handler) new_handler(); else return NULL;
  386.     }
  387. }
  388.  
  389. /************************************************************************/
  390. /*    Purpose..:     Dispose memory                                            */
  391. /*    Input....:    pointer to memory or 0L (no action if 0L)                */
  392. /*    Return...:    ---                                                        */
  393. /************************************************************************/
  394. void OPERATOR_DELETE(void *ptr)
  395. {
  396.     if(ptr)
  397.     {
  398.         ptr=(char *)ptr-4;
  399.         if((*(long *)ptr=-*(long *)ptr)==0L) DisposPtr((Ptr)ptr);
  400.     }
  401. }
  402.  
  403. #else
  404.  
  405. //    no operator new/delete defined
  406.  
  407. #endif
  408.